package com.tangyuan.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangyuan.common.algorithm.EuclideanMetric;
import com.tangyuan.dto.UserActionByUserIdDto;
import com.tangyuan.feignapis.user.IUserActionFeignClient;
import com.tangyuan.feignapis.user.IUserLikeFeignClient;
import com.tangyuan.mapper.UserCoordinationMapper;
import com.tangyuan.model.UserCoordination;
import com.tangyuan.model.UserLike;
import com.tangyuan.service.UserCoordinationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 小梁
 * @since 2020-12-03
 */
@Slf4j
@Service
public class UserCoordinationServiceImpl extends ServiceImpl<UserCoordinationMapper, UserCoordination> implements UserCoordinationService {

    @Autowired
    IUserLikeFeignClient userLikeFeignClient;
    @Autowired
    UserCoordinationMapper userCoordinationMapper;
    @Autowired
    IUserActionFeignClient userActionFeignClient;


    /**
     * 相邻用户的电影id列表(user_coordination表)
     * @param userId
     * @return List<Long>
     */
    @Override
    public List<Long> getMovieIdList(Long userId) {
        List<UserCoordination> records = this.getUserCoordinationPageByUserId1(userId);
        if(CollectionUtil.isEmpty(records)){
            return new ArrayList<>();
        }
        List<Long> longs = records.stream().map(UserCoordination::getUserId2).collect(Collectors.toList());

        UserActionByUserIdDto userActionByUserIdDto = new UserActionByUserIdDto();
        userActionByUserIdDto.setUserId(userId);
        userActionByUserIdDto.setUserIds(longs);
        userActionByUserIdDto.setJustScore(new BigDecimal("2.6"));
        return userActionFeignClient.getUserActionByUserIdDto(userActionByUserIdDto);
    }
    @Override
    public List<UserCoordination> getUserCoordinationPageByUserId1(Long userId) {
        if(userId == null || userId == 0){
            return new ArrayList<>();
        }
        return userCoordinationMapper.getUserCoordinationPageByUserId1(userId);
    }

    @Override
    public List<UserCoordination> getUserCoordinationByUserId1(List<Long> ids) {
        if(CollectionUtils.isEmpty(ids)){
            return new ArrayList<>();
        }
        return userCoordinationMapper.getUserCoordinationByUserId1(ids);
    }

    /**
     * 获取最后一次更新时间
     * @return
     */
    @Override
    public Date getMaxUpdateTime() {
        return baseMapper.getMaxUpdateTime();
    }

    @Override
    public void saveUserCoordination(List<UserLike> likes) {
        long l = System.currentTimeMillis();
        //昨日活跃的用户
        List<Long> userIds = likes.stream().map(UserLike::getUserId).collect(Collectors.toList());
        //获取已经存在的 UserCoordination数据
        List<UserCoordination> coordinationList = this.getUserCoordinationByUserId1(userIds);
        //需要保存的数据
        List<UserCoordination> saveCoordinationList =  new ArrayList<>();
        int i = 1;
        for (UserLike like : likes) {
            //已经循环过的数据不在保存
            List<UserLike> userLikes = likes.subList(i, likes.size());
            i++;
            for (UserLike userLike : userLikes) {
                if(like.getUserId().equals(userLike.getUserId())){
                    continue;
                }
                UserCoordination userCoordination = null;
                //查看是否存在 存在则更新,不存在则创建
                List<UserCoordination> coordination = coordinationList.stream().filter(
                                coo ->  coo.getUserId2().equals(like.getUserId())
                                        && coo.getUserId1().equals(userLike.getUserId()))
                        .collect(Collectors.toList());
                if(!CollectionUtils.isEmpty(coordination)){
                    userCoordination = coordination.get(0);
                }else {
                    userCoordination = new UserCoordination();
                    userCoordination.setUserId1(userLike.getUserId());
                    userCoordination.setUserId2(like.getUserId());
                    userCoordination.setCreateTime(new Date());
                }
                userCoordination.setUpdateTime(new Date());
                //用户与用户的相似度
                userCoordination.setDistance(EuclideanMetric.euclideanDis(userLike, like));
                saveCoordinationList.add(userCoordination);
            }
        }
        //保存入库
        this.saveOrUpdateBatch(saveCoordinationList);
        log.info("saveUserCoordination:执行时间"+(System.currentTimeMillis() - l));
    }

    /**
     * 根据用户查询UserCoordination2表 (表设计 userId2 小于 userId1)
     * @param userId1 userId1
     * @param userId2 userId2
     * @return UserCoordination2表
     */
    @Override
    public UserCoordination getUserCoordination(Long userId1, Long userId2) {
        if(userId1 == null || userId1 == 0 || userId2 == null || userId2 == 0){
            return null;
        }
        if(userId2 > userId1){
            return baseMapper.getUserCoordination(userId2,userId1);
        }
        return baseMapper.getUserCoordination(userId1,userId2);
    }
}
